import React, { ReactNode } from "react"
import * as auth from 'auth-provider'
import { User } from "pages/project-list/search-panel";
import { http } from "utils/http";
import { useMount } from "utils";
import { useAsync } from "utils/use-async";
import { FullPageErrorFallback, FullPageLoading } from "components/lib";

interface AuthForm {
  username: string;
  password: string
}

// 初始化user,使页面在刷新时仍有user信息不会退出页面
const bootstrapUser = async () => {
  let user = null
  const token = auth.getToken()
  if (token) {
    const data = await http('me', {token})
    user = data.user
  }
  return user
}

const AuthContext = React.createContext<{
  user: User | null;
  login: (form: AuthForm) => Promise<void>;
  register: (form: AuthForm) => Promise<void>;
  logout: () => Promise<void>;
} | undefined>(undefined)
AuthContext.displayName = 'AuthContext'

export const AuthProvider = ({children}:{children:ReactNode}) => {
  const {data: user, error, isLoading, isIdle, isError, run, setData: setUser} = useAsync<User | null>()
  
  // point free : 当箭头函数的参数 (user) => setUser(user)   =====>  setUser
  const login = (form:AuthForm) => auth.login(form).then(setUser)
  const register = (form:AuthForm) => auth.register(form).then(setUser)
  const logout = () => auth.logout().then(() => setUser(null))

  useMount(() => {
    run(bootstrapUser())
  })

  if(isLoading || isIdle) {
    return <FullPageLoading/>
  }

  if(isError) {
    return <FullPageErrorFallback error={error} />
  }

  return <AuthContext.Provider children={children} value={{user, login, register, logout}} />
}

export const useAuth = () => {
  const context = React.useContext(AuthContext)
  if(!context) {
    throw new Error('useAuth必须在AuthProvider中使用')
  }
  return context
}